<a href='https://github.com/angular/angular.js/edit/v1.4.x/src/ngAnimate/module.js?message=docs(ngAnimate)%3A%20describe%20your%20change...#L17' class='improve-docs btn btn-primary'><i class="glyphicon glyphicon-edit">&nbsp;</i>Improve this Doc</a>


<h1>
  <code>ngAnimate</code>
</h1>


  <h2>Installation</h2>

  <p>First include <code>angular-animate.js</code> in your HTML:</p>

  <pre><code>&lt;script src=&quot;angular.js&quot;&gt;&#10;&lt;script src=&quot;angular-animate.js&quot;&gt;</code></pre>

  <p>You can download this file from the following places:</p>
  <ul>
    <li>
      <a href="https://developers.google.com/speed/libraries/devguide#angularjs">Google CDN</a><br>
      e.g. <code>//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-animate.js</code>
    </li>
    <li>
      <a href="http://bower.io">Bower</a><br>
      e.g. <pre><code>bower install angular-animate@X.Y.Z</code></pre>
    </li>
    <li>
      <a href="http://code.angularjs.org/">code.angularjs.org</a><br>
      e.g. <pre><code>&quot;//code.angularjs.org/X.Y.Z/angular-animate.js&quot;</code></pre>
    </li>
  </ul>
  <p>where X.Y.Z is the AngularJS version you are running.</p>
  <p>Then load the module in your application by adding it as a dependent module:</p>
  <pre><code>angular.module(&#39;app&#39;, [&#39;ngAnimate&#39;]);</code></pre>

  <p>With that you&apos;re ready to get started!</p>


<p>The <code>ngAnimate</code> module provides support for CSS-based animations (keyframes and transitions) as well as JavaScript-based animations via
callback hooks. Animations are not enabled by default, however, by including <code>ngAnimate</code> the animation hooks are enabled for an Angular app.</p>
<div doc-module-components="ngAnimate"></div>

<h1 id="usage">Usage</h1>
<p>Simply put, there are two ways to make use of animations when ngAnimate is used: by using <strong>CSS</strong> and <strong>JavaScript</strong>. The former works purely based
using CSS (by using matching CSS selectors/styles) and the latter triggers animations that are registered via <code>module.animation()</code>. For
both CSS and JS animations the sole requirement is to have a matching <code>CSS class</code> that exists both in the registered animation and within
the HTML element that the animation will be triggered on.</p>
<h2 id="directive-support">Directive Support</h2>
<p>The following directives are &quot;animation aware&quot;:</p>
<table>
<thead>
<tr>
<th>Directive</th>
<th>Supported Animations</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="api/ng/directive/ngRepeat#animations">ngRepeat</a></td>
<td>enter, leave and move</td>
</tr>
<tr>
<td><a href="api/ngRoute/directive/ngView#animations">ngView</a></td>
<td>enter and leave</td>
</tr>
<tr>
<td><a href="api/ng/directive/ngInclude#animations">ngInclude</a></td>
<td>enter and leave</td>
</tr>
<tr>
<td><a href="api/ng/directive/ngSwitch#animations">ngSwitch</a></td>
<td>enter and leave</td>
</tr>
<tr>
<td><a href="api/ng/directive/ngIf#animations">ngIf</a></td>
<td>enter and leave</td>
</tr>
<tr>
<td><a href="api/ng/directive/ngClass#animations">ngClass</a></td>
<td>add and remove (the CSS class(es) present)</td>
</tr>
<tr>
<td><a href="api/ng/directive/ngShow#animations">ngShow</a> &amp; <a href="api/ng/directive/ngHide#animations">ngHide</a></td>
<td>add and remove (the ng-hide class value)</td>
</tr>
<tr>
<td><a href="api/ng/directive/form#animation-hooks">form</a> &amp; <a href="api/ng/directive/ngModel#animation-hooks">ngModel</a></td>
<td>add and remove (dirty, pristine, valid, invalid &amp; all other validations)</td>
</tr>
<tr>
<td><a href="api/ngMessages#animations">ngMessages</a></td>
<td>add and remove (ng-active &amp; ng-inactive)</td>
</tr>
<tr>
<td><a href="api/ngMessages#animations">ngMessage</a></td>
<td>enter and leave</td>
</tr>
</tbody>
</table>
<p>(More information can be found by visiting each the documentation associated with each directive.)</p>
<h2 id="css-based-animations">CSS-based Animations</h2>
<p>CSS-based animations with ngAnimate are unique since they require no JavaScript code at all. By using a CSS class that we reference between our HTML
and CSS code we can create an animation that will be picked up by Angular when an the underlying directive performs an operation.</p>
<p>The example below shows how an <code>enter</code> animation can be made possible on an element using <code>ng-if</code>:</p>
<pre><code class="lang-html">&lt;div ng-if=&quot;bool&quot; class=&quot;fade&quot;&gt;
   Fade me in out
&lt;/div&gt;
&lt;button ng-click=&quot;bool=true&quot;&gt;Fade In!&lt;/button&gt;
&lt;button ng-click=&quot;bool=false&quot;&gt;Fade Out!&lt;/button&gt;
</code></pre>
<p>Notice the CSS class <strong>fade</strong>? We can now create the CSS transition code that references this class:</p>
<pre><code class="lang-css">/* The starting CSS styles for the enter animation */
.fade.ng-enter {
  transition:0.5s linear all;
  opacity:0;
}

/* The finishing CSS styles for the enter animation */
.fade.ng-enter.ng-enter-active {
  opacity:1;
}
</code></pre>
<p>The key thing to remember here is that, depending on the animation event (which each of the directives above trigger depending on what&#39;s going on) two
generated CSS classes will be applied to the element; in the example above we have <code>.ng-enter</code> and <code>.ng-enter-active</code>. For CSS transitions, the transition
code <strong>must</strong> be defined within the starting CSS class (in this case <code>.ng-enter</code>). The destination class is what the transition will animate towards.</p>
<p>If for example we wanted to create animations for <code>leave</code> and <code>move</code> (ngRepeat triggers move) then we can do so using the same CSS naming conventions:</p>
<pre><code class="lang-css">/* now the element will fade out before it is removed from the DOM */
.fade.ng-leave {
  transition:0.5s linear all;
  opacity:1;
}
.fade.ng-leave.ng-leave-active {
  opacity:0;
}
</code></pre>
<p>We can also make use of <strong>CSS Keyframes</strong> by referencing the keyframe animation within the starting CSS class:</p>
<pre><code class="lang-css">/* there is no need to define anything inside of the destination
CSS class since the keyframe will take charge of the animation */
.fade.ng-leave {
  animation: my_fade_animation 0.5s linear;
  -webkit-animation: my_fade_animation 0.5s linear;
}

@keyframes my_fade_animation {
  from { opacity:1; }
  to { opacity:0; }
}

@-webkit-keyframes my_fade_animation {
  from { opacity:1; }
  to { opacity:0; }
}
</code></pre>
<p>Feel free also mix transitions and keyframes together as well as any other CSS classes on the same element.</p>
<h3 id="css-class-based-animations">CSS Class-based Animations</h3>
<p>Class-based animations (animations that are triggered via <code>ngClass</code>, <code>ngShow</code>, <code>ngHide</code> and some other directives) have a slightly different
naming convention. Class-based animations are basic enough that a standard transition or keyframe can be referenced on the class being added
and removed.</p>
<p>For example if we wanted to do a CSS animation for <code>ngHide</code> then we place an animation on the <code>.ng-hide</code> CSS class:</p>
<pre><code class="lang-html">&lt;div ng-show=&quot;bool&quot; class=&quot;fade&quot;&gt;
  Show and hide me
&lt;/div&gt;
&lt;button ng-click=&quot;bool=true&quot;&gt;Toggle&lt;/button&gt;

&lt;style&gt;
.fade.ng-hide {
  transition:0.5s linear all;
  opacity:0;
}
&lt;/style&gt;
</code></pre>
<p>All that is going on here with ngShow/ngHide behind the scenes is the <code>.ng-hide</code> class is added/removed (when the hidden state is valid). Since
ngShow and ngHide are animation aware then we can match up a transition and ngAnimate handles the rest.</p>
<p>In addition the addition and removal of the CSS class, ngAnimate also provides two helper methods that we can use to further decorate the animation
with CSS styles.</p>
<pre><code class="lang-html">&lt;div ng-class=&quot;{on:onOff}&quot; class=&quot;highlight&quot;&gt;
  Highlight this box
&lt;/div&gt;
&lt;button ng-click=&quot;onOff=!onOff&quot;&gt;Toggle&lt;/button&gt;

&lt;style&gt;
.highlight {
  transition:0.5s linear all;
}
.highlight.on-add {
  background:white;
}
.highlight.on {
  background:yellow;
}
.highlight.on-remove {
  background:black;
}
&lt;/style&gt;
</code></pre>
<p>We can also make use of CSS keyframes by placing them within the CSS classes.</p>
<h3 id="css-staggering-animations">CSS Staggering Animations</h3>
<p>A Staggering animation is a collection of animations that are issued with a slight delay in between each successive operation resulting in a
curtain-like effect. The ngAnimate module (versions &gt;=1.2) supports staggering animations and the stagger effect can be
performed by creating a <strong>ng-EVENT-stagger</strong> CSS class and attaching that class to the base CSS class used for
the animation. The style property expected within the stagger class can either be a <strong>transition-delay</strong> or an
<strong>animation-delay</strong> property (or both if your animation contains both transitions and keyframe animations).</p>
<pre><code class="lang-css">.my-animation.ng-enter {
  /* standard transition code */
  transition: 1s linear all;
  opacity:0;
}
.my-animation.ng-enter-stagger {
  /* this will have a 100ms delay between each successive leave animation */
  transition-delay: 0.1s;

  /* As of 1.4.4, this must always be set: it signals ngAnimate
    to not accidentally inherit a delay property from another CSS class */
  transition-duration: 0s;
}
.my-animation.ng-enter.ng-enter-active {
  /* standard transition styles */
  opacity:1;
}
</code></pre>
<p>Staggering animations work by default in ngRepeat (so long as the CSS class is defined). Outside of ngRepeat, to use staggering animations
on your own, they can be triggered by firing multiple calls to the same event on $animate. However, the restrictions surrounding this
are that each of the elements must have the same CSS className value as well as the same parent element. A stagger operation
will also be reset if one or more animation frames have passed since the multiple calls to <code>$animate</code> were fired.</p>
<p>The following code will issue the <strong>ng-leave-stagger</strong> event on the element provided:</p>
<pre><code class="lang-js">var kids = parent.children();

$animate.leave(kids[0]); //stagger index=0
$animate.leave(kids[1]); //stagger index=1
$animate.leave(kids[2]); //stagger index=2
$animate.leave(kids[3]); //stagger index=3
$animate.leave(kids[4]); //stagger index=4

window.requestAnimationFrame(function() {
  //stagger has reset itself
  $animate.leave(kids[5]); //stagger index=0
  $animate.leave(kids[6]); //stagger index=1

  $scope.$digest();
});
</code></pre>
<p>Stagger animations are currently only supported within CSS-defined animations.</p>
<h3 id="the-ng-animate-css-class">The <code>ng-animate</code> CSS class</h3>
<p>When ngAnimate is animating an element it will apply the <code>ng-animate</code> CSS class to the element for the duration of the animation.
This is a temporary CSS class and it will be removed once the animation is over (for both JavaScript and CSS-based animations).</p>
<p>Therefore, animations can be applied to an element using this temporary class directly via CSS.</p>
<pre><code class="lang-css">.zipper.ng-animate {
  transition:0.5s linear all;
}
.zipper.ng-enter {
  opacity:0;
}
.zipper.ng-enter.ng-enter-active {
  opacity:1;
}
.zipper.ng-leave {
  opacity:1;
}
.zipper.ng-leave.ng-leave-active {
  opacity:0;
}
</code></pre>
<p>(Note that the <code>ng-animate</code> CSS class is reserved and it cannot be applied on an element directly since ngAnimate will always remove
the CSS class once an animation has completed.)</p>
<h2 id="javascript-based-animations">JavaScript-based Animations</h2>
<p>ngAnimate also allows for animations to be consumed by JavaScript code. The approach is similar to CSS-based animations (where there is a shared
CSS class that is referenced in our HTML code) but in addition we need to register the JavaScript animation on the module. By making use of the
<code>module.animation()</code> module function we can register the ainmation.</p>
<p>Let&#39;s see an example of a enter/leave animation using <code>ngRepeat</code>:</p>
<pre><code class="lang-html">&lt;div ng-repeat=&quot;item in items&quot; class=&quot;slide&quot;&gt;
  {{ item }}
&lt;/div&gt;
</code></pre>
<p>See the <strong>slide</strong> CSS class? Let&#39;s use that class to define an animation that we&#39;ll structure in our module code by using <code>module.animation</code>:</p>
<pre><code class="lang-js">myModule.animation(&#39;.slide&#39;, [function() {
  return {
    // make note that other events (like addClass/removeClass)
    // have different function input parameters
    enter: function(element, doneFn) {
      jQuery(element).fadeIn(1000, doneFn);

      // remember to call doneFn so that angular
      // knows that the animation has concluded
    },

    move: function(element, doneFn) {
      jQuery(element).fadeIn(1000, doneFn);
    },

    leave: function(element, doneFn) {
      jQuery(element).fadeOut(1000, doneFn);
    }
  }
}]
</code></pre>
<p>The nice thing about JS-based animations is that we can inject other services and make use of advanced animation libraries such as
greensock.js and velocity.js.</p>
<p>If our animation code class-based (meaning that something like <code>ngClass</code>, <code>ngHide</code> and <code>ngShow</code> triggers it) then we can still define
our animations inside of the same registered animation, however, the function input arguments are a bit different:</p>
<pre><code class="lang-html">&lt;div ng-class=&quot;color&quot; class=&quot;colorful&quot;&gt;
  this box is moody
&lt;/div&gt;
&lt;button ng-click=&quot;color=&#39;red&#39;&quot;&gt;Change to red&lt;/button&gt;
&lt;button ng-click=&quot;color=&#39;blue&#39;&quot;&gt;Change to blue&lt;/button&gt;
&lt;button ng-click=&quot;color=&#39;green&#39;&quot;&gt;Change to green&lt;/button&gt;
</code></pre>
<pre><code class="lang-js">myModule.animation(&#39;.colorful&#39;, [function() {
  return {
    addClass: function(element, className, doneFn) {
      // do some cool animation and call the doneFn
    },
    removeClass: function(element, className, doneFn) {
      // do some cool animation and call the doneFn
    },
    setClass: function(element, addedClass, removedClass, doneFn) {
      // do some cool animation and call the doneFn
    }
  }
}]
</code></pre>
<h2 id="css-js-animations-together">CSS + JS Animations Together</h2>
<p>AngularJS 1.4 and higher has taken steps to make the amalgamation of CSS and JS animations more flexible. However, unlike earlier versions of Angular,
defining CSS and JS animations to work off of the same CSS class will not work anymore. Therefore the example below will only result in <strong>JS animations taking
charge of the animation</strong>:</p>
<pre><code class="lang-html">&lt;div ng-if=&quot;bool&quot; class=&quot;slide&quot;&gt;
  Slide in and out
&lt;/div&gt;
</code></pre>
<pre><code class="lang-js">myModule.animation(&#39;.slide&#39;, [function() {
  return {
    enter: function(element, doneFn) {
      jQuery(element).slideIn(1000, doneFn);
    }
  }
}]
</code></pre>
<pre><code class="lang-css">.slide.ng-enter {
  transition:0.5s linear all;
  transform:translateY(-100px);
}
.slide.ng-enter.ng-enter-active {
  transform:translateY(0);
}
</code></pre>
<p>Does this mean that CSS and JS animations cannot be used together? Do JS-based animations always have higher priority? We can make up for the
lack of CSS animations by using the <code>$animateCss</code> service to trigger our own tweaked-out, CSS-based animations directly from
our own JS-based animation code:</p>
<pre><code class="lang-js">myModule.animation(&#39;.slide&#39;, [&#39;$animateCss&#39;, function($animateCss) {
  return {
    enter: function(element, doneFn) {
       // this will trigger `.slide.ng-enter` and `.slide.ng-enter-active`.
      var runner = $animateCss(element, {
        event: &#39;enter&#39;,
        structural: true
      }).start();
       runner.done(doneFn);
    }
  }
}]
</code></pre>
<p>The nice thing here is that we can save bandwidth by sticking to our CSS-based animation code and we don&#39;t need to rely on a 3rd-party animation framework.</p>
<p>The <code>$animateCss</code> service is very powerful since we can feed in all kinds of extra properties that will be evaluated and fed into a CSS transition or
keyframe animation. For example if we wanted to animate the height of an element while adding and removing classes then we can do so by providing that
data into <code>$animateCss</code> directly:</p>
<pre><code class="lang-js">myModule.animation(&#39;.slide&#39;, [&#39;$animateCss&#39;, function($animateCss) {
  return {
    enter: function(element, doneFn) {
      var runner = $animateCss(element, {
        event: &#39;enter&#39;,
        structural: true,
        addClass: &#39;maroon-setting&#39;,
        from: { height:0 },
        to: { height: 200 }
      }).start();

      runner.done(doneFn);
    }
  }
}]
</code></pre>
<p>Now we can fill in the rest via our transition CSS code:</p>
<pre><code class="lang-css">/* the transition tells ngAnimate to make the animation happen */
.slide.ng-enter { transition:0.5s linear all; }

/* this extra CSS class will be absorbed into the transition
since the $animateCss code is adding the class */
.maroon-setting { background:red; }
</code></pre>
<p>And <code>$animateCss</code> will figure out the rest. Just make sure to have the <code>done()</code> callback fire the <code>doneFn</code> function to signal when the animation is over.</p>
<p>To learn more about what&#39;s possible be sure to visit the <a href="api/ngAnimate/service/$animateCss">$animateCss service</a>.</p>
<h2 id="animation-anchoring-via-ng-animate-ref-">Animation Anchoring (via <code>ng-animate-ref</code>)</h2>
<p>ngAnimate in AngularJS 1.4 comes packed with the ability to cross-animate elements between
structural areas of an application (like views) by pairing up elements using an attribute
called <code>ng-animate-ref</code>.</p>
<p>Let&#39;s say for example we have two views that are managed by <code>ng-view</code> and we want to show
that there is a relationship between two components situated in within these views. By using the
<code>ng-animate-ref</code> attribute we can identify that the two components are paired together and we
can then attach an animation, which is triggered when the view changes.</p>
<p>Say for example we have the following template code:</p>
<pre><code class="lang-html">&lt;!-- index.html --&gt;
&lt;div ng-view class=&quot;view-animation&quot;&gt;
&lt;/div&gt;

&lt;!-- home.html --&gt;
&lt;a href=&quot;#/banner-page&quot;&gt;
  &lt;img src=&quot;./banner.jpg&quot; class=&quot;banner&quot; ng-animate-ref=&quot;banner&quot;&gt;
&lt;/a&gt;

&lt;!-- banner-page.html --&gt;
&lt;img src=&quot;./banner.jpg&quot; class=&quot;banner&quot; ng-animate-ref=&quot;banner&quot;&gt;
</code></pre>
<p>Now, when the view changes (once the link is clicked), ngAnimate will examine the
HTML contents to see if there is a match reference between any components in the view
that is leaving and the view that is entering. It will scan both the view which is being
removed (leave) and inserted (enter) to see if there are any paired DOM elements that
contain a matching ref value.</p>
<p>The two images match since they share the same ref value. ngAnimate will now create a
transport element (which is a clone of the first image element) and it will then attempt
to animate to the position of the second image element in the next view. For the animation to
work a special CSS class called <code>ng-anchor</code> will be added to the transported element.</p>
<p>We can now attach a transition onto the <code>.banner.ng-anchor</code> CSS class and then
ngAnimate will handle the entire transition for us as well as the addition and removal of
any changes of CSS classes between the elements:</p>
<pre><code class="lang-css">.banner.ng-anchor {
  /* this animation will last for 1 second since there are
         two phases to the animation (an `in` and an `out` phase) */
  transition:0.5s linear all;
}
</code></pre>
<p>We also <strong>must</strong> include animations for the views that are being entered and removed
(otherwise anchoring wouldn&#39;t be possible since the new view would be inserted right away).</p>
<pre><code class="lang-css">.view-animation.ng-enter, .view-animation.ng-leave {
  transition:0.5s linear all;
  position:fixed;
  left:0;
  top:0;
  width:100%;
}
.view-animation.ng-enter {
  transform:translateX(100%);
}
.view-animation.ng-leave,
.view-animation.ng-enter.ng-enter-active {
  transform:translateX(0%);
}
.view-animation.ng-leave.ng-leave-active {
  transform:translateX(-100%);
}
</code></pre>
<p>Now we can jump back to the anchor animation. When the animation happens, there are two stages that occur:
an <code>out</code> and an <code>in</code> stage. The <code>out</code> stage happens first and that is when the element is animated away
from its origin. Once that animation is over then the <code>in</code> stage occurs which animates the
element to its destination. The reason why there are two animations is to give enough time
for the enter animation on the new element to be ready.</p>
<p>The example above sets up a transition for both the in and out phases, but we can also target the out or
in phases directly via <code>ng-anchor-out</code> and <code>ng-anchor-in</code>.</p>
<pre><code class="lang-css">.banner.ng-anchor-out {
  transition: 0.5s linear all;

  /* the scale will be applied during the out animation,
         but will be animated away when the in animation runs */
  transform: scale(1.2);
}

.banner.ng-anchor-in {
  transition: 1s linear all;
}
</code></pre>
<h3 id="anchoring-demo">Anchoring Demo</h3>
<p>  

<div>
  <a ng-click="openPlunkr('examples/example-anchoringExample', $event)" class="btn pull-right">
    <i class="glyphicon glyphicon-edit">&nbsp;</i>
    Edit in Plunker</a>

  <div class="runnable-example"
      path="examples/example-anchoringExample"
      module="anchoringExample"
      name="anchoringExample"
      id="anchoringExample"
      deps="angular-animate.js;angular-route.js"
      animations="true">

  
    <div class="runnable-example-file" 
      name="index.html"
      language="html"
      type="html">
      <pre><code>&lt;a href=&quot;#/&quot;&gt;Home&lt;/a&gt;&#10;&lt;hr /&gt;&#10;&lt;div class=&quot;view-container&quot;&gt;&#10;  &lt;div ng-view class=&quot;view&quot;&gt;&lt;/div&gt;&#10;&lt;/div&gt;</code></pre>
    </div>
  
    <div class="runnable-example-file" 
      name="script.js"
      language="js"
      type="js">
      <pre><code>angular.module(&#39;anchoringExample&#39;, [&#39;ngAnimate&#39;, &#39;ngRoute&#39;])&#10;.config([&#39;$routeProvider&#39;, function($routeProvider) {&#10;  $routeProvider.when(&#39;/&#39;, {&#10;    templateUrl: &#39;home.html&#39;,&#10;    controller: &#39;HomeController as home&#39;&#10;  });&#10;  $routeProvider.when(&#39;/profile/:id&#39;, {&#10;    templateUrl: &#39;profile.html&#39;,&#10;    controller: &#39;ProfileController as profile&#39;&#10;  });&#10;}])&#10;.run([&#39;$rootScope&#39;, function($rootScope) {&#10;  $rootScope.records = [&#10;    { id:1, title: &quot;Miss Beulah Roob&quot; },&#10;    { id:2, title: &quot;Trent Morissette&quot; },&#10;    { id:3, title: &quot;Miss Ava Pouros&quot; },&#10;    { id:4, title: &quot;Rod Pouros&quot; },&#10;    { id:5, title: &quot;Abdul Rice&quot; },&#10;    { id:6, title: &quot;Laurie Rutherford Sr.&quot; },&#10;    { id:7, title: &quot;Nakia McLaughlin&quot; },&#10;    { id:8, title: &quot;Jordon Blanda DVM&quot; },&#10;    { id:9, title: &quot;Rhoda Hand&quot; },&#10;    { id:10, title: &quot;Alexandrea Sauer&quot; }&#10;  ];&#10;}])&#10;.controller(&#39;HomeController&#39;, [function() {&#10;  //empty&#10;}])&#10;.controller(&#39;ProfileController&#39;, [&#39;$rootScope&#39;, &#39;$routeParams&#39;, function($rootScope, $routeParams) {&#10;  var index = parseInt($routeParams.id, 10);&#10;  var record = $rootScope.records[index - 1];&#10;&#10;  this.title = record.title;&#10;  this.id = record.id;&#10;}]);</code></pre>
    </div>
  
    <div class="runnable-example-file" 
      name="home.html"
      language="html"
      type="html">
      <pre><code>&lt;h2&gt;Welcome to the home page&lt;/h1&gt;&#10;&lt;p&gt;Please click on an element&lt;/p&gt;&#10;&lt;a class=&quot;record&quot;&#10;   ng-href=&quot;#/profile/{{ record.id }}&quot;&#10;   ng-animate-ref=&quot;{{ record.id }}&quot;&#10;   ng-repeat=&quot;record in records&quot;&gt;&#10;  {{ record.title }}&#10;&lt;/a&gt;</code></pre>
    </div>
  
    <div class="runnable-example-file" 
      name="profile.html"
      language="html"
      type="html">
      <pre><code>&lt;div class=&quot;profile record&quot; ng-animate-ref=&quot;{{ profile.id }}&quot;&gt;&#10;  {{ profile.title }}&#10;&lt;/div&gt;</code></pre>
    </div>
  
    <div class="runnable-example-file" 
      name="animations.css"
      language="css"
      type="css">
      <pre><code>.record {&#10;  display:block;&#10;  font-size:20px;&#10;}&#10;.profile {&#10;  background:black;&#10;  color:white;&#10;  font-size:100px;&#10;}&#10;.view-container {&#10;  position:relative;&#10;}&#10;.view-container &gt; .view.ng-animate {&#10;  position:absolute;&#10;  top:0;&#10;  left:0;&#10;  width:100%;&#10;  min-height:500px;&#10;}&#10;.view.ng-enter, .view.ng-leave,&#10;.record.ng-anchor {&#10;  transition:0.5s linear all;&#10;}&#10;.view.ng-enter {&#10;  transform:translateX(100%);&#10;}&#10;.view.ng-enter.ng-enter-active, .view.ng-leave {&#10;  transform:translateX(0%);&#10;}&#10;.view.ng-leave.ng-leave-active {&#10;  transform:translateX(-100%);&#10;}&#10;.record.ng-anchor-out {&#10;  background:red;&#10;}</code></pre>
    </div>
  

    <iframe class="runnable-example-frame" src="examples/example-anchoringExample/index.html" name="example-anchoringExample"></iframe>
  </div>
</div>


</p>
<h3 id="how-is-the-element-transported-">How is the element transported?</h3>
<p>When an anchor animation occurs, ngAnimate will clone the starting element and position it exactly where the starting
element is located on screen via absolute positioning. The cloned element will be placed inside of the root element
of the application (where ng-app was defined) and all of the CSS classes of the starting element will be applied. The
element will then animate into the <code>out</code> and <code>in</code> animations and will eventually reach the coordinates and match
the dimensions of the destination element. During the entire animation a CSS class of <code>.ng-animate-shim</code> will be applied
to both the starting and destination elements in order to hide them from being visible (the CSS styling for the class
is: <code>visibility:hidden</code>). Once the anchor reaches its destination then it will be removed and the destination element
will become visible since the shim class will be removed.</p>
<h3 id="how-is-the-morphing-handled-">How is the morphing handled?</h3>
<p>CSS Anchoring relies on transitions and keyframes and the internal code is intelligent enough to figure out
what CSS classes differ between the starting element and the destination element. These different CSS classes
will be added/removed on the anchor element and a transition will be applied (the transition that is provided
in the anchor class). Long story short, ngAnimate will figure out what classes to add and remove which will
make the transition of the element as smooth and automatic as possible. Be sure to use simple CSS classes that
do not rely on DOM nesting structure so that the anchor element appears the same as the starting element (since
the cloned element is placed inside of root element which is likely close to the body element).</p>
<p>Note that if the root element is on the <code>&lt;html&gt;</code> element then the cloned node will be placed inside of body.</p>
<h2 id="using-animate-in-your-directive-code">Using $animate in your directive code</h2>
<p>So far we&#39;ve explored how to feed in animations into an Angular application, but how do we trigger animations within our own directives in our application?
By injecting the <code>$animate</code> service into our directive code, we can trigger structural and class-based hooks which can then be consumed by animations. Let&#39;s
imagine we have a greeting box that shows and hides itself when the data changes</p>
<pre><code class="lang-html">&lt;greeting-box active=&quot;onOrOff&quot;&gt;Hi there&lt;/greeting-box&gt;
</code></pre>
<pre><code class="lang-js">ngModule.directive(&#39;greetingBox&#39;, [&#39;$animate&#39;, function($animate) {
  return function(scope, element, attrs) {
    attrs.$observe(&#39;active&#39;, function(value) {
      value ? $animate.addClass(element, &#39;on&#39;) : $animate.removeClass(element, &#39;on&#39;);
    });
  });
}]);
</code></pre>
<p>Now the <code>on</code> CSS class is added and removed on the greeting box component. Now if we add a CSS class on top of the greeting box element
in our HTML code then we can trigger a CSS or JS animation to happen.</p>
<pre><code class="lang-css">/* normally we would create a CSS class to reference on the element */
greeting-box.on { transition:0.5s linear all; background:green; color:white; }
</code></pre>
<p>The <code>$animate</code> service contains a variety of other methods like <code>enter</code>, <code>leave</code>, <code>animate</code> and <code>setClass</code>. To learn more about what&#39;s
possible be sure to visit the <a href="api/ng/service/$animate">$animate service API page</a>.</p>
<h3 id="preventing-collisions-with-third-party-libraries">Preventing Collisions With Third Party Libraries</h3>
<p>Some third-party frameworks place animation duration defaults across many element or className
selectors in order to make their code small and reuseable. This can lead to issues with ngAnimate, which
is expecting actual animations on these elements and has to wait for their completion.</p>
<p>You can prevent this unwanted behavior by using a prefix on all your animation classes:</p>
<pre><code class="lang-css">/* prefixed with animate- */
.animate-fade-add.animate-fade-add-active {
  transition:1s linear all;
  opacity:0;
}
</code></pre>
<p>You then configure <code>$animate</code> to enforce this prefix:</p>
<pre><code class="lang-js">$animateProvider.classNameFilter(/animate-/);
</code></pre>
<p>This also may provide your application with a speed boost since only specific elements containing CSS class prefix
will be evaluated for animation when any DOM changes occur in the application.</p>
<h2 id="callbacks-and-promises">Callbacks and Promises</h2>
<p>When <code>$animate</code> is called it returns a promise that can be used to capture when the animation has ended. Therefore if we were to trigger
an animation (within our directive code) then we can continue performing directive and scope related activities after the animation has
ended by chaining onto the returned promise that animation method returns.</p>
<pre><code class="lang-js">// somewhere within the depths of the directive
$animate.enter(element, parent).then(function() {
  //the animation has completed
});
</code></pre>
<p>(Note that earlier versions of Angular prior to v1.4 required the promise code to be wrapped using <code>$scope.$apply(...)</code>. This is not the case
anymore.)</p>
<p>In addition to the animation promise, we can also make use of animation-related callbacks within our directives and controller code by registering
an event listener using the <code>$animate</code> service. Let&#39;s say for example that an animation was triggered on our view
routing controller to hook into that:</p>
<pre><code class="lang-js">ngModule.controller(&#39;HomePageController&#39;, [&#39;$animate&#39;, function($animate) {
  $animate.on(&#39;enter&#39;, ngViewElement, function(element) {
    // the animation for this route has completed
  }]);
}])
</code></pre>
<p>(Note that you will need to trigger a digest within the callback to get angular to notice any scope-related changes.)</p>


<div class="component-breakdown">
  <h2>Module Components</h2>
  
  <div>
    <h3 class="component-heading" id="service">Service</h3>
    <table class="definition-table">
      <tr>
        <th>Name</th>
        <th>Description</th>
      </tr>
      
      <tr>
        <td><a href="api/ngAnimate/service/$animateCss">$animateCss</a></td>
        <td><p>The <code>$animateCss</code> service is a useful utility to trigger customized CSS-based transitions/keyframes
from a JavaScript-based animation or directly from a directive. The purpose of <code>$animateCss</code> is NOT
to side-step how <code>$animate</code> and ngAnimate work, but the goal is to allow pre-existing animations or
directives to create more complex animations that can be purely driven using CSS code.</p>
</td>
      </tr>
      
      <tr>
        <td><a href="api/ngAnimate/service/$animate">$animate</a></td>
        <td><p>The ngAnimate <code>$animate</code> service documentation is the same for the core <code>$animate</code> service.</p>
</td>
      </tr>
      
    </table>
  </div>
  
</div>




